package com.jerry.ops;

import com.alibaba.fastjson.JSON;
import com.jerry.ops.config.tenant.Feature;
import com.jerry.ops.model.Tenant;
import com.jerry.ops.model.TenantFeature;
import com.jerry.ops.repo.TenantFeatureRepository;
import com.jerry.ops.repo.TenantRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author fish
 */
@SpringBootApplication
@Slf4j
@EnableAsync
public class OpsApplication implements ApplicationRunner {

	@Autowired
	TenantRepository tenantRepository;

	@Autowired
	TenantFeatureRepository tenantFeatureRepository;

	public static void main(String[] args) {
		SpringApplication.run(OpsApplication.class, args);
	}

	@Override
	public void run(ApplicationArguments args) {
		Tenant adminTenant = tenantRepository
				.findAllByTenantName("Admin")
				.stream().findAny().orElse(initAdmin());
		addAllFeatureToAdmin(adminTenant);

		addGaFeatureToAllTenant();
	}

	private Tenant initAdmin(){
		Tenant tenant= new Tenant();
		tenant.setTenantName("Admin");
		return tenantRepository.save(tenant);
	}

	private void addAllFeatureToAdmin(Tenant adminTenant){
		Long tenantId = adminTenant.getId();
		List<Feature> features = tenantFeatureRepository
				.findAllByTenantId(tenantId)
				.map(TenantFeature::getFeature)
				.toList();

		List<TenantFeature> featureList = Stream.of(Feature.values())
		 		.filter(feature -> !features.contains(feature))
				.map(feature -> new TenantFeature(tenantId, feature))
				.toList();

		tenantFeatureRepository.saveAll(featureList);
	}

	private void addGaFeatureToAllTenant(){
		var currentGaTenantList = tenantFeatureRepository
				.findAllByFeatureIn(Feature.getAllGaFeature())
				.map(TenantFeature::getFeature)
				.stream().distinct().toList();

		var gaFeatureList = Feature.getAllGaFeature();

		var tenants = tenantRepository.findAll();

		List<TenantFeature> features = new ArrayList<>();
		for (Feature feature: gaFeatureList){
			for (Tenant tenant:tenants){
				if (!"Admin".equals(tenant.getTenantName())) {
					features.add(new TenantFeature(tenant.getId(),feature));
				}
			}
		}

		log.info("Add features to tenant {}", JSON.toJSON(features));
		tenantFeatureRepository.saveAll(features);
	}
}
